home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / FM-EXT20.ZIP / ENHDOS.PAS next >
Pascal/Delphi Source File  |  1995-09-20  |  52KB  |  2,139 lines

  1. {
  2. I'm very glad to be useful and to post the enhanced DOS unit for Turbo Pascal
  3. 7.0. It includes lots of nice routines written on inline asm, combined with
  4. short comments and explanations. All you have in standard DOS unit you may
  5. find in EnhDOS as well except of Exec and SwapVectors. Sure, the full source
  6. code!
  7.  
  8. What is good?
  9. -----------------
  10.  
  11. 1. Fast! (because of the asm)
  12. 2. Flexible! (less procedures, more functions, lots of parameters)
  13. 3. Good error-handling routines. (don't need to care to check errors at all)
  14. 4. _Strong_ file service. (lots of file functions)
  15. 5. Lots of additional DOS service functions that can't be found in any standard
  16.    or non-standard Pascal, C,... library.
  17. 6. Windows (tm) compatible (means you may use these routines when developing
  18.    Windows (tm) applications.
  19. 7. Own memory allocate/release routines. (used DOS memory allocation)
  20. 8. Free. Released to a Public Domain.
  21.  
  22. What is bad?
  23. -----------------
  24.  
  25. 1. Requires Borland Turbo Pascal version 7.0 or later (7.01)
  26. 2. Requires DOS 3.1 or later. Sorry guys, wanna cool service - need later DOS.
  27. 3. Won't run on XT personal computers. (uses 286 instructions)
  28. 4. No more strings. (all string-type names are of PChar type)
  29. 5. Exec and SwapVectors not implemented. If you'd like this code, I will
  30.    continue modifying this unit and will eventually add the above functions
  31.    too.
  32.  
  33. Well, routines were checked on IBM PS/2 386SX, seems like work fine!
  34.  
  35. Greetingz to
  36. -----------------
  37.  
  38.  Bas van Gaalen (cool asm programmer and my PASCAL area friend ;)
  39.  Dj Murdoch (best explainer ;)
  40.  Gayle Davis (SWAG live forever) Feel free to place it into a next SWAG bundle.
  41.  Ralph Brown (brilliant idea to make the interrupt list)
  42.  Alex Grischenko (whose asm help was very appreciated)
  43.  ...and all of you, guys!
  44.  
  45. Material used
  46. -----------------
  47.  
  48. Borland Pascal 7.0 Runtime Library source code
  49. Ralph Brown's Interrupt List
  50. Tech Help 4.0
  51.  
  52.  
  53. You may use this source-code-software in ANY purpose. Code may be changed.
  54. If some of the routines won't work, please send me a message.
  55. If you don't mind, please leave my copyright strings as they are.}
  56.  
  57. Unit EnhDOS;
  58. (*
  59.   Turbo Pascal 7.0 - ENHDOS.PAS
  60.  
  61.   Enhanced DOS interface unit for DOS 3.1+ ***  Version 1.1  April, 1994.
  62.   Copyright (c) 1994  by Andrew Eigus           Fidonet 2:5100/33
  63.  
  64.   Runtime Library Portions Copyright (c) 1991,92 Borland International }
  65.  
  66.   THIS UNIT SOURCE IS FREE
  67. *)
  68.  
  69. interface
  70.  
  71. {$X+} { Enable extended syntax }
  72. {$G+} { Enable 286+ instructions }
  73.  
  74. const
  75.  
  76.   { My copyright information }
  77.  
  78.   Copyright : PChar = 'Portions Copyright (c) 1994 by Andrew Eigus';
  79.  
  80.   { GetDriveType return values }
  81.  
  82.   dtError     = $00; { Bad drive }
  83.   dtFixed     = $01; { Fixed drive }
  84.   dtRemovable = $02; { Removable drive }
  85.   dtRemote    = $03; { Remote (network) drive }
  86.  
  87.   { Handle file open modes (om) constants }
  88.  
  89.   omRead           = $00; { Open file for input only }
  90.   omWrite          = $01; { Open file for output only }
  91.   omReadWrite      = $02; { Open file for input or/and output (both modes) }
  92.   omShareCompat    = $00; { Modes used when SHARE.EXE loaded }
  93.   omShareExclusive = $10;
  94.   omShareDenyWrite = $20;
  95.   omShareDenyRead  = $30;
  96.   omShareDenyNone  = $40;
  97.  
  98.   { Maximum file name component string lengths }
  99.  
  100.   fsPathName       = 79;
  101.   fsDirectory      = 67;
  102.   fsFileSpec       = 12;
  103.   fsFileName       = 8;
  104.   fsExtension      = 4;
  105.  
  106.   { FileSplit return flags }
  107.  
  108.   fcExtension      = $0001;
  109.   fcFileName       = $0002;
  110.   fcDirectory      = $0004;
  111.   fcWildcards      = $0008;
  112.  
  113.   { File attributes (fa) constants }
  114.  
  115.   faNormal         = $00;
  116.   faReadOnly       = $01;
  117.   faHidden         = $02;
  118.   faSysFile        = $04;
  119.   faVolumeID       = $08;
  120.   faDirectory      = $10;
  121.   faArchive        = $20;
  122.   faAnyFile        = $3F;
  123.  
  124.   { Seek start offset (sk) constants }
  125.  
  126.   skStart = 0; { Seek position relative to the beginning of a file }
  127.   skPos   = 1; { Seek position relative to a current file position }
  128.   skEnd   = 2; { Seek position relative to the end of a file }
  129.  
  130.   { Error handler function (fr) result codes }
  131.  
  132.   frOk    = 0; { Continue program }
  133.   frRetry = 1; { Retry function once again }
  134.  
  135.   { Function codes (only passed to error handler routine) (fn) constants }
  136.  
  137.   fnGetDPB         = $3200;
  138.   fnGetDiskSize    = $3600;
  139.   fnGetDiskFree    = $3601;
  140.   fnGetCountryInfo = $3800;
  141.   fnSetDate        = $2B00;
  142.   fnSetTime        = $2D00;
  143.   fnIsFixedDisk    = $4408;
  144.   fnIsNetworkDrive = $4409;
  145.   fnCreateDir      = $3900;
  146.   fnRemoveDir      = $3A00;
  147.   fnGetCurDir      = $4700;
  148.   fnSetCurDir      = $3B00;
  149.   fnDeleteFile     = $4100;
  150.   fnRenameFile     = $5600;
  151.   fnGetFileAttr    = $4300;
  152.   fnSetFileAttr    = $4301;
  153.   fnFindFirst      = $4E00;
  154.   fnFindNext       = $4F00;
  155.   fnCreateFile     = $5B00;
  156.   fnCreateTempFile = $5A00;
  157.   fnOpenFile       = $3D00;
  158.   fnRead           = $3F00;
  159.   fnWrite          = $4000;
  160.   fnSeek           = $4200;
  161.   fnGetFDateTime   = $5700;
  162.   fnSetFDateTime   = $5701;
  163.   fnCloseFile      = $3E00;
  164.   fnMemAlloc       = $4800;
  165.   fnMemFree        = $4900;
  166.  
  167.   { DOS 3.x+ errors/return codes }
  168.  
  169.   dosrOk                = 0;   { Success }
  170.   dosrInvalidFuncNumber = 1;   { Invalid DOS function number }
  171.   dosrFileNotFound      = 2;   { File not found }
  172.   dosrPathNotFound      = 3;   { Path not found }
  173.   dosrTooManyOpenFiles  = 4;   { Too many open files }
  174.   dosrFileAccessDenied  = 5;   { File access denied }
  175.   dosrInvalidFileHandle = 6;   { Invalid file handle }
  176.   dosrNotEnoughMemory   = 8;   { Not enough memory }
  177.   dosrInvalidEnvment    = 10;  { Invalid environment }
  178.   dosrInvalidFormat     = 11;  { Invalid format }
  179.   dosrInvalidAccessCode = 12;  { Invalid file access code }
  180.   dosrInvalidDrive      = 15;  { Invalid drive number }
  181.   dosrCantRemoveDir     = 16;  { Cannot remove current directory }
  182.   dosrCantRenameDrives  = 17;  { Cannot rename across drives }
  183.   dosrNoMoreFiles       = 18;  { No more files }
  184.  
  185. type
  186.  
  187.   TPathStr = array[0..fsPathName] of Char;
  188.   TDirStr  = array[0..fsDirectory] of Char;
  189.   TNameStr = array[0..fsFileName] of Char;
  190.   TExtStr  = array[0..fsExtension] of Char;
  191.   TFileStr = array[0..fsFileSpec] of Char;
  192.  
  193.   { Disk information block structure }
  194.  
  195.   PDiskParamBlock = ^TDiskParamBlock;
  196.   TDiskParamBlock = record
  197.     Drive : byte;             { Disk drive number (0=A, 1=B, 2=C...) }
  198.     SubunitNum : byte;        { Sub-unit number from driver device header }
  199.     SectSize : word;          { Number of bytes per sector }
  200.     SectPerClust : byte;      { Number of sectors per cluster -1
  201.                                 (max sector in cluster) }
  202.     ClustToSectShft : byte;   { Cluster-to-sector shift }
  203.     BootSize : word;          { Reserved sectors (boot secs; start of root dir}
  204.     FATCount : byte;          { Number of FATs }
  205.     MaxDir : word;            { Number of directory entries allowed in root }
  206.     DataSect : word;          { Sector number of first data cluster }
  207.     Clusters : word;          { Total number of allocation units (clusters)
  208.                                 +2 (number of highest cluster) }
  209.     FATSectors : byte;        { Sectors needed by first FAT }
  210.     RootSect : word;          { Sector number of start of root directory }
  211.     DeviceHeader : pointer;   { Address of device header }
  212.     Media : byte;             { Media descriptor byte }
  213.     AccessFlag : byte;        { 0 if drive has been accessed }
  214.     NextPDB : pointer         { Address of next DPB (0FFFFh if last) }
  215.   end;
  216.  
  217.   { Disk allocation data structure }
  218.  
  219.   PDiskAllocInfo = ^TDiskAllocInfo;
  220.   TDiskAllocInfo = record
  221.     FATId : byte;             { FAT Id }
  222.     Clusters : word;          { Number of allocation units (clusters) }
  223.     SectPerClust : byte;      { Number of sectors per cluster }
  224.     SectSize : word           { Number of bytes per sector }
  225.   end;
  226.  
  227.   { Country information structure }
  228.  
  229.   PCountryInfo = ^TCountryInfo;
  230.   TCountryInfo = record
  231.     DateFormat : word; { Date format value may be one of the following:
  232.                          0 - Month, Day, Year     (USA)
  233.                          1 - Day, Month, Year     (Europe)
  234.                          2 - Year, Month, Day     (Japan) }
  235.  
  236.     CurrencySymbol : array[0..4] of Char; { Currency symbol string }
  237.     ThousandsChar : byte; { Thousands separator character }
  238.     reserved1 : byte;
  239.     DecimalChar : byte;   { Decimal separator character }
  240.     reserved2 : byte;
  241.     DateChar : byte;      { Date separator character }
  242.     reserved3 : byte;
  243.     TimeChar : byte;      { Time separator character }
  244.     reserved4 : byte;
  245.     CurrencyFormat : byte; { Currency format:
  246.                              $XXX.XX
  247.                              XXX.XX$
  248.                              $ XXX.XX
  249.                              XXX.XX $
  250.                              XXX$XX }
  251.  
  252.     Digits : byte;          { Number of digits after decimal in currency }
  253.     TimeFormat : byte;      { Time format may be one of the following:
  254.                               bit 0 = 0 if 12 hour clock
  255.                                   1 if 24 hour clock }
  256.  
  257.     MapRoutine : pointer;   { Address of case map routine FAR CALL,
  258.                               AL - character to map to upper case [>=80h] }
  259.  
  260.     DataListChar : byte;    { Data-list separator character }
  261.     reserved5 : byte;
  262.     reserved6 : array[1..10] of Char
  263.   end;
  264.  
  265.   THandle = Word; { Handle type (file handle and memory handle functions) }
  266.  
  267.   { Error handler function }
  268.  
  269.   TErrorFunc = function(ErrCode : integer; FuncCode : word) : byte;
  270.  
  271.   { Search record used by FindFirst and FindNext }
  272.  
  273.   TSearchRec = record
  274.     Fill : array[1..21] of Byte;
  275.     Attr : byte;
  276.     Time : longint;
  277.     Size : longint;
  278.     Name : TFileStr
  279.   end;
  280.  
  281.   { Date and time record used by PackTime and UnpackTime }
  282.  
  283.   TDateTime = record
  284.     Year,
  285.     Month,
  286.     Day,
  287.     Hour,
  288.     Min,
  289.     Sec : word
  290.   end;
  291.  
  292.  
  293. var
  294.   DOSResult : integer; { Error status variable }
  295.   TempStr : array[0..High(String)] of Char;
  296.  
  297. function SetErrorHandler(Handler : TErrorFunc) : pointer;
  298. function Pas2PChar(S : string) : PChar;
  299. Function Str2Pas(S : PChar) : String;
  300.  
  301. function GetInDOSFlag : boolean;
  302. function GetDOSVersion : word;
  303. function GetSwitchChar : char;
  304. function SetSwitchChar(Switch : char) : byte;
  305. function GetCountryInfo(var Info : TCountryInfo) : integer;
  306. procedure GetDate(var Year : word; var Month, Day, DayOfWeek : byte);
  307. function SetDate(Year : word; Month, Day : byte) : boolean;
  308. procedure GetTime(var Hour, Minute, Second, Sec100 : byte);
  309. function SetTime(Hour, Minute, Second, Sec100 : byte) : boolean;
  310. function GetCBreak : boolean;
  311. function SetCBreak(Break : boolean) : boolean;
  312. function GetVerify : boolean;
  313. function SetVerify(Verify : boolean) : boolean;
  314. function GetArgCount : integer;
  315. function GetArgStr(Dest : PChar; Index : integer; MaxLen : word) : PChar;
  316. function GetEnvVar(VarName : PChar) : PChar;
  317. function GetIntVec(IntNo : byte; var Vector : pointer) : pointer;
  318. function SetIntVec(IntNo : byte; Vector : pointer) : pointer;
  319.  
  320. function GetDTA : pointer;
  321. function GetCurDisk : byte;
  322. function SetCurDisk(Drive : byte) : byte;
  323. procedure GetDriveAllocInfo(Drive : byte; var Info : TDiskAllocInfo);
  324. function GetDPB(Drive : byte; var DPB : TDiskParamBlock) : integer;
  325. function DiskSize(Drive : byte) : longint;
  326. function DiskFree(Drive : byte) : longint;
  327. function IsFixedDisk(Drive : byte) : boolean;
  328. function IsNetworkDrive(Drive : byte) : boolean;
  329. function GetDriveType(Drive : byte) : byte;
  330.  
  331. function CreateDir(Dir : PChar) : integer;
  332. function RemoveDir(Dir : PChar) : integer;
  333. function GetCurDir(Drive : byte; Dir : PChar) : integer;
  334. function SetCurDir(Dir : PChar) : integer;
  335.  
  336. function DeleteFile(Path : PChar) : integer;
  337. function RenameFile(OldPath, NewPath : PChar) : integer;
  338. function ExistsFile(Path : PChar) : boolean;
  339. function GetFileAttr(Path : PChar) : integer;
  340. function SetFileAttr(Path : PChar; Attr : word) : integer;
  341. function FindFirst(Path : PChar; Attr: word; var F : TSearchRec) : integer;
  342. function FindNext(var F : TSearchRec) : integer;
  343. procedure UnpackTime(P : longint; var T : TDateTime);
  344. function PackTime(var T : TDateTime) : longint;
  345.  
  346. function h_CreateFile(Path : PChar) : THandle;
  347. function h_CreateTempFile(Path : PChar) : THandle;
  348. function h_OpenFile(Path : PChar; Mode : byte) : THandle;
  349. function h_Read(Handle : THandle; var Buffer; Count : word) : word;
  350. function h_Write(Handle : THandle; var Buffer; Count : word) : word;
  351. function h_Seek(Handle : THandle; SeekPos : longint; Start : byte) : longint;
  352. function h_FilePos(Handle : THandle) : longint;
  353. function h_FileSize(Handle : THandle) : longint;
  354. function h_Eof(Handle : THandle) : boolean;
  355. function h_GetFTime(Handle : THandle) : longint;
  356. function h_SetFTime(Handle : THandle; DateTime : longint) : longint;
  357. function h_CloseFile(Handle : THandle) : integer;
  358.  
  359. function MemAlloc(Size : longint) : pointer;
  360. function MemFree(P : pointer) : integer;
  361.  
  362. function FileSearch(Dest, Name, List : PChar) : PChar;
  363. function FileExpand(Dest, Name : PChar) : PChar;
  364. function FileSplit(Path, Dir, Name, Ext : PChar) : word;
  365.  
  366. implementation
  367.  
  368. {$IFDEF Windows}
  369. {$DEFINE ProtectedMode}
  370. {$ENDIF}
  371.  
  372. {$IFDEF DPMI}
  373. {$DEFINE ProtectedMode}
  374. {$ENDIF}
  375.  
  376. {$IFDEF Windows}
  377.  
  378. uses WinTypes, WinProcs, Strings;
  379.  
  380. {$ELSE}
  381.  
  382. uses Strings;
  383.  
  384. {$ENDIF}
  385.  
  386. const DOS = $21; { DOS interrupt number }
  387.  
  388. var
  389.   ErrorHandler : TErrorFunc;
  390.  
  391. Function SetErrorHandler;
  392. { Sets the new error handler to hook all errors returned by EnhDOS functions,
  393.   and returns the pointer to an old interrupt handler routine }
  394. Begin
  395.   SetErrorHandler := @ErrorHandler;
  396.   ErrorHandler := Handler
  397. End; { SetErrorHandler }
  398.  
  399. Function Pas2PChar(S : string) : PChar;
  400. { Returns PChar type equivalent of the S variable. Use this function
  401.   to convert strings to PChars }
  402. Begin
  403.   Pas2PChar := StrPCopy(TempStr, S)
  404. End; { Pas2PChar }
  405.  
  406. Function Str2Pas(S : PChar) : String;
  407. { Returns PChar type equivalent of the S variable. Use this function
  408.   to convert strings to PChars }
  409. Begin
  410.   Str2Pas:=StrPas(S)
  411. End;
  412.  
  413.  
  414. {$IFDEF Windows}
  415.  
  416. procedure AnsiDosFunc; assembler;
  417. asm
  418.   PUSH DS
  419.   PUSH CX
  420.   PUSH AX
  421.   MOV SI,DI
  422.   PUSH ES
  423.   POP DS
  424.   LEA DI,TempStr
  425.   PUSH SS
  426.   POP ES
  427.   MOV CX,fsPathName
  428.   CLD
  429. @@1:
  430.   LODSB
  431.   OR  AL,AL
  432.   JE  @@2
  433.   STOSB
  434.   LOOP @@1
  435. @@2:
  436.   XOR AL,AL
  437.   STOSB
  438.   LEA DI,TempStr
  439.   PUSH SS
  440.   PUSH DI
  441.   PUSH SS
  442.   PUSH DI
  443.   CALL AnsiToOem
  444.   POP AX
  445.   POP CX
  446.   LEA DX,TempStr
  447.   PUSH SS
  448.   POP DS
  449.   INT DOS
  450.   POP DS
  451. end; { AnsiDosFunc /Windows }
  452.  
  453. {$ELSE}
  454.  
  455. procedure AnsiDosFunc; assembler;
  456. asm
  457.   PUSH DS
  458.   MOV DX,DI
  459.   PUSH ES
  460.   POP DS
  461.   INT DOS
  462.   POP DS
  463. end; { AnsiDosFunc }
  464.  
  465. {$ENDIF}
  466.  
  467. Function GetInDOSFlag; assembler;
  468. { GETINDOSFLAG - DOS service function
  469.   Description: Returns the current state of InDOS flag; fn=34h
  470.   Returns: True if a DOS operation is being performed, False if there is
  471.            no DOS command that currently is running }
  472. Asm
  473.   MOV AH,34h
  474.   INT DOS
  475.   MOV AL,BYTE PTR [ES:BX]
  476. End; { GetInDOSFlag }
  477.  
  478. Function GetDOSVersion; assembler;
  479. { GETDOSVERSION - DOS service function
  480.   Description: Retrieves DOS version number; fn=30h
  481.   Returns: Major DOS version number in low-order byte,
  482.            minor version number in high-order byte of word }
  483. Asm
  484.   MOV AH,30h
  485.   INT DOS
  486. End; { GetDOSVersion }
  487.  
  488. Function GetSwitchChar; assembler;
  489. { GETSWITCHCHAR - DOS service function
  490.   Description: Retrieves DOS command line default switch character; fn=37h
  491.   Returns: Switch character ('/', '-', ...) or FFh if unsupported subfunction }
  492. Asm
  493.   MOV AH,37h
  494.   XOR AL,AL
  495.   INT DOS
  496.   CMP AL,0FFh
  497.   JE  @@1
  498.   MOV AL,DL
  499. @@1:
  500. End; { GetSwitchChar }
  501.  
  502. Function SetSwitchChar; assembler;
  503. { SETSWITCHCHAR - DOS service function
  504.   Description: Sets new DOS command line switch character; fn=37h
  505.   Returns: FFh if unsupported subfunction, any other value success }
  506. Asm
  507.   MOV AX,3701h
  508.   MOV DL,Switch
  509.   INT DOS
  510. End; { SetSwitchChar }
  511.  
  512. Function GetCountryInfo; assembler;
  513. { GETCOUNTRYINFO - DOS service function
  514.   Description: Retrieves country information; fn=38h
  515.   Returns: Country code if successful, negative DOS error code otherwise }
  516. Asm
  517. @@1:
  518.   PUSH DS
  519.   MOV AH,38h
  520.   XOR AL,AL
  521.   LDS DX,Info
  522.   INT DOS
  523.   POP DS
  524.   JC  @@2
  525.   MOV AX,BX
  526.   MOV DOSResult,dosrOk
  527.   JMP @@3
  528. @@2:
  529.   MOV DOSResult,AX { save error code in global variable }
  530.   PUSH AX     { store error code }
  531.   PUSH fnGetCountryInfo { store function code }
  532.   CALL ErrorHandler
  533.   CMP AL,frRetry
  534.   JE  @@1
  535.   POP AX
  536.   NEG AX
  537. @@3:
  538. End; { GetCountryInfo }
  539.  
  540. Procedure GetDate; assembler;
  541. { GETDATE - DOS service function
  542.   Description: Retrieves the current date set in the operating system.
  543.                Ranges of the values returned are: Year 1980-2099,
  544.                Month 1-12, Day 1-31 and DayOfWeek 0-6 (0 corresponds to
  545.                Sunday) }
  546. Asm
  547.   MOV AH,2AH
  548.   INT DOS
  549.   XOR AH,AH
  550.   LES DI,DayOfWeek
  551.   STOSB
  552.   MOV AL,DL
  553.   LES DI,Day
  554.   STOSB
  555.   MOV AL,DH
  556.   LES DI,Month
  557.   STOSB
  558.   XCHG AX,CX
  559.   LES DI,Year
  560.   STOSW
  561. End; { GetDate }
  562.  
  563. Function SetDate; assembler;
  564. { SETDATE - DOS service function
  565.   Description: Sets the current date in the operating system. Valid
  566.                parameter ranges are: Year 1980-2099, Month 1-12 and
  567.                Day 1-31
  568.   Returns: True if the date was set, False if the date is not valid }
  569. Asm
  570.   MOV CX,Year
  571.   MOV DH,Month
  572.   MOV DL,Day
  573.   MOV AH,2BH
  574.   INT DOS
  575.   CMP AL,0
  576.   JE  @@1
  577.   MOV DOSResult,AX
  578.   PUSH AX
  579.   PUSH fnSetDate
  580.   CALL ErrorHandler
  581.   MOV AL,True
  582. @@1:
  583.   NOT AL
  584. End; { SetDate }
  585.  
  586. Procedure GetTime; assembler;
  587. { GETTIME - DOS service function
  588.   Description: Returns the current time set in the operating system.
  589.                Ranges of the values returned are: Hour 0-23, Minute 0-59,
  590.                Second 0-59 and Sec100 (hundredths of seconds) 0-99 }
  591. Asm
  592.   MOV AH,2CH
  593.   INT DOS
  594.   XOR AH,AH
  595.   MOV AL,DL
  596.   LES DI,Sec100
  597.   STOSB
  598.   MOV AL,DH
  599.   LES DI,Second
  600.   STOSB
  601.   MOV AL,CL
  602.   LES DI,Minute
  603.   STOSB
  604.   MOV AL,CH
  605.   LES DI,Hour
  606.   STOSB
  607. End; { GetTime }
  608.  
  609. Function SetTime; assembler;
  610. { SETTIME - DOS service function
  611.   Description: Sets the time in the operating system. Valid
  612.                parameter ranges are: Hour 0-23, Minute 0-59, Second 0-59 and
  613.                Sec100 (hundredths of seconds) 0-99
  614.   Returns: True if the time was set, False if the time is not valid }
  615. Asm
  616.   MOV CH,Hour
  617.   MOV CL,Minute
  618.   MOV DH,Second
  619.   MOV DL,Sec100
  620.   MOV AH,2DH
  621.   INT DOS
  622.   CMP AL,0
  623.   JE  @@1
  624.   MOV DOSResult,AX
  625.   PUSH AX
  626.   PUSH fnSetTime
  627.   CALL ErrorHandler
  628.   MOV AL,True
  629. @@1:
  630.   NOT AL
  631. End; { SetTime }
  632.  
  633. Function GetCBreak; assembler;
  634. { GETCBREAK - DOS service function
  635.   Description: Retrieves Control-Break state; fn=3300h
  636.   Returns: Current Ctrl-Break state }
  637. Asm
  638.   MOV AX,3300h
  639.   INT DOS
  640.   MOV AL,DL
  641. End; { GetCBreak }
  642.  
  643. Function SetCBreak; assembler;
  644. { SETCBREAK - DOS service function
  645.   Description: Sets new Control-Break state; fn=3300h
  646.   Returns: Old Ctrl-Break state }
  647. Asm
  648.   CALL GetCBreak
  649.   PUSH AX
  650.   MOV AX,3301h
  651.   MOV DL,Break
  652.   INT DOS
  653.   POP AX
  654. End; { SetCBreak }
  655.  
  656. Function GetVerify; assembler;
  657. { GETVERIFY - DOS service function
  658.   Description: Returns the state of the verify flag in DOS.
  659.                When off (False), disk writes are not verified.
  660.                When on (True), all disk writes are verified to insure proper
  661.                writing; fn=54h
  662.   Returns: State of the verify flag }
  663. Asm
  664.   MOV AH,54H
  665.   INT DOS
  666. End; { GetVerify }
  667.  
  668. Function SetVerify; assembler;
  669. { SETVERIFY - DOS service function
  670.   Description: Sets the state of the verify flag in DOS; fn=2Eh
  671.   Returns: Previous state of the verify flag }
  672. Asm
  673.   CALL GetVerify
  674.   PUSH AX
  675.   MOV AL,Verify
  676.   MOV AH,2EH
  677.   INT DOS
  678.   POP AX
  679. End; { SetVerify }
  680.  
  681. {$IFDEF Windows}
  682.  
  683. Procedure ArgStrCount; assembler;
  684. Asm
  685.   LDS SI,CmdLine
  686.   CLD
  687. @@1:
  688.   LODSB
  689.   OR  AL,AL
  690.   JE  @@2
  691.   CMP AL,' '
  692.   JBE @@1
  693. @@2:
  694.   DEC SI
  695.   MOV BX,SI
  696. @@3:
  697.   LODSB
  698.   CMP AL,' '
  699.   JA  @@3
  700.   DEC SI
  701.   MOV AX,SI
  702.   SUB AX,BX
  703.   JE  @@4
  704.   LOOP @@1
  705. @@4:
  706. End; { ArgStrCount /Windows }
  707.  
  708. Function GetArgCount; assembler;
  709. { GETARGCOUNT - DOS service function
  710.   Description: Returns the number of parameters passed to the
  711.                program on the command line
  712.   Returns: Actual number of command line parameters }
  713.  
  714. Asm
  715.   PUSH DS
  716.   XOR  CX,CX
  717.   CALL ArgStrCount
  718.   XCHG AX,CX
  719.   NEG AX
  720.   POP DS
  721. End; { GetArgCount /Windows }
  722.  
  723. Function GetArgStr; assembler;
  724. { GETARGSTR - DOS service function
  725.   Description: Returns the specified parameter from the command line
  726.   Returns: ASCIIZ parameter, or an empty string if Index is less than zero
  727.            or greater than GetArgCount. If Index is zero, GetArgStr returns
  728.            the filename of the current module. The maximum length of the
  729.            string returned in Dest is given by the MaxLen parameter. The
  730.            returned value is Dest }
  731.  
  732. Asm
  733.   MOV CX,Index
  734.   JCXZ @@2
  735.   PUSH DS
  736.   CALL ArgStrCount
  737.   MOV SI,BX
  738.   LES DI,Dest
  739.   MOV CX,MaxLen
  740.   CMP CX,AX
  741.   JB  @@1
  742.   XCHG AX,CX
  743. @@1:
  744.   REP MOVSB
  745.   XCHG AX,CX
  746.   STOSB
  747.   POP DS
  748.   JMP @@3
  749. @@2:
  750.   PUSH HInstance
  751.   PUSH WORD PTR [Dest+2]
  752.   PUSH WORD PTR [Dest]
  753.   MOV AX,MaxLen
  754.   INC AX
  755.   PUSH AX
  756.   CALL GetModuleFileName
  757. @@3:
  758.   MOV AX,WORD PTR [Dest]
  759.   MOV DX,WORD PTR [Dest+2]
  760. End; { GetArgStr /Windows }
  761.  
  762. {$ELSE}
  763.  
  764. Procedure ArgStrCount; assembler;
  765. Asm
  766.   MOV DS,PrefixSeg
  767.   MOV SI,80H
  768.   CLD
  769.   LODSB
  770.   MOV DL,AL
  771.   XOR DH,DH
  772.   ADD DX,SI
  773. @@1:
  774.   CMP SI,DX
  775.   JE  @@2
  776.   LODSB
  777.   CMP AL,' '
  778.   JBE @@1
  779.   DEC SI
  780. @@2:
  781.   MOV BX,SI
  782. @@3:
  783.   CMP SI,DX
  784.   JE  @@4
  785.   LODSB
  786.   CMP AL,' '
  787.   JA  @@3
  788.   DEC SI
  789. @@4:
  790.   MOV AX,SI
  791.   SUB AX,BX
  792.   JE  @@5
  793.   LOOP @@1
  794. @@5:
  795. End; { ArgStrCount }
  796.  
  797. Function GetArgCount; assembler;
  798. { GETARGCOUNT - DOS service function
  799.   Description: Returns the number of parameters passed to the
  800.                program on the command line
  801.   Returns: Actual number of command line parameters }
  802. Asm
  803.   PUSH DS
  804.   XOR CX,CX
  805.   CALL ArgStrCount
  806.   XCHG AX,CX
  807.   NEG AX
  808.   POP DS
  809. End; { GetArgCount }
  810.  
  811. Function GetArgStr; assembler;
  812. { GETARGSTR - DOS service function
  813.   Description: Returns the specified parameter from the command line
  814.   Returns: ASCIIZ parameter, or an empty string if Index is less than zero
  815.            or greater than GetArgCount. If Index is zero, GetArgStr returns
  816.            the filename of the current module. The maximum length of the
  817.            string returned in Dest is given by the MaxLen parameter. The
  818.            returned value is Dest }
  819. Asm
  820.   PUSH DS
  821.   MOV CX,Index
  822.   JCXZ @@1
  823.   CALL ArgStrCount
  824.   MOV SI,BX
  825.   JMP @@4
  826. @@1:
  827.   MOV AH,30H
  828.   INT DOS
  829.   CMP AL,3
  830.   MOV AX,0
  831.   JB  @@4
  832.   MOV DS,PrefixSeg
  833.   MOV ES,DS:WORD PTR 2CH
  834.   XOR DI,DI
  835.   CLD
  836. @@2:
  837.   CMP AL,ES:[DI]
  838.   JE  @@3
  839.   MOV CX,-1
  840.   REPNE SCASB
  841.   JMP @@2
  842. @@3:
  843.   ADD DI,3
  844.   MOV SI,DI
  845.   PUSH ES
  846.   POP DS
  847.   MOV CX,256
  848.   REPNE SCASB
  849.   XCHG AX,CX
  850.   NOT AL
  851. @@4:
  852.   LES DI,Dest
  853.   MOV CX,MaxLen
  854.   CMP CX,AX
  855.   JB  @@5
  856.   XCHG AX,CX
  857. @@5:
  858.   REP MOVSB
  859.   XCHG AX,CX
  860.   STOSB
  861.   MOV AX,WORD PTR [Dest]
  862.   MOV DX,WORD PTR [Dest+2]
  863.   POP DS
  864. End; { GetArgStr }
  865.  
  866. {$ENDIF}
  867.  
  868. Function GetEnvVar;
  869. { GETENVVAR - DOS service function
  870.   Description: Retrieves a specified DOS environment variable
  871.   Returns: A pointer to the value of a specified variable,
  872.            i.e. a pointer to the first character after the equals
  873.            sign (=) in the environment entry given by VarName.
  874.            VarName is case insensitive. GetEnvVar returns NIL if
  875.            the specified environment variable does not exist }
  876. var
  877.   L : word;
  878.   P : PChar;
  879. Begin
  880.   L := StrLen(VarName);
  881. {$IFDEF Windows}
  882.   P := GetDosEnvironment;
  883. {$ELSE}
  884.   P := Ptr(Word(Ptr(PrefixSeg, $2C)^), 0);
  885. {$ENDIF}
  886.   while P^ <> #0 do
  887.   begin
  888.     if (StrLIComp(P, VarName, L) = 0) and (P[L] = '=') then
  889.     begin
  890.       GetEnvVar := P + L + 1;
  891.       Exit;
  892.     end;
  893.     Inc(P, StrLen(P) + 1)
  894.   end;
  895.   GetEnvVar := nil
  896. End; { GetEnvVar }
  897.  
  898. Function GetIntVec; assembler;
  899. { GETINTVEC - DOS service function
  900.   Description: Retrieves the address stored in the specified interrupt vector
  901.   Returns: A pointer to this address }
  902. Asm
  903.   MOV AL,IntNo
  904.   MOV AH,35H
  905.   INT DOS
  906.   MOV AX,ES
  907.   LES DI,Vector
  908.   CLD
  909.   MOV DX,BX
  910.   XCHG AX,BX
  911.   STOSW
  912.   XCHG AX,BX
  913.   STOSW
  914.   XCHG AX,DX
  915. End; { GetIntVec }
  916.  
  917. Function SetIntVec; assembler;
  918. { SETINTVEC - DOS Service function
  919.   Description: Sets the address in the interrupt vector table for the
  920.                specified interrupt
  921.   Returns: The old address of the specified interrupt vector }
  922. Asm
  923.   LES DI,Vector
  924.   PUSH WORD PTR IntNo
  925.   PUSH ES
  926.   PUSH DI
  927.   PUSH CS
  928.   CALL GetIntVec
  929.   PUSH DX
  930.   PUSH AX
  931.   PUSH DS
  932.   LDS DX,Vector
  933.   MOV AL,IntNo
  934.   MOV AH,25H
  935.   INT DOS
  936.   POP DS
  937.   POP AX
  938.   POP DX
  939. End; { SetIntVec }
  940.  
  941. Function GetDTA; assembler;
  942. { GETDTA - DOS service function
  943.   Description: Retrieves a pointer address to a DOS data exchange buffer (DTA).
  944.                By default, DTA address has the offset PSP+80h and the size of
  945.                128 bytes. DTA is used to access files with the FCB method;
  946.                fn=2Fh
  947.   Returns: A pointer address to DTA }
  948. Asm
  949.   MOV AH,2Fh
  950.   INT DOS
  951.   MOV DX,BX { store offset }
  952.   MOV AX,ES { store segment }
  953. End; { GetDTA }
  954.  
  955. Function GetCurDisk; assembler;
  956. { GETCURDISK - DOS disk service function
  957.   Description: Retrieves number of disk currently being active; fn=19h
  958.   Returns: Default (current, active) disk number }
  959. Asm
  960.   MOV AH,19h
  961.   INT DOS
  962. End; { GetCurDisk }
  963.  
  964. Function SetCurDisk; assembler;
  965. { SETCURDISK - DOS disk service function
  966.   Description: Sets current (default/active) drive; fn=0Eh
  967.   Returns: Number of disks in the system }
  968. Asm
  969.   MOV AH,0Eh
  970.   MOV DL,Drive
  971.   INT DOS
  972. End; { SetCurDisk }
  973.  
  974. Procedure GetDriveAllocInfo; assembler;
  975. { GETDRIVEALLOCINFO - DOS disk service function
  976.   Description: Retrieves disk allocation information; fn=1Ch
  977.   Retrieves Info structure }
  978. Asm
  979.   PUSH DS
  980.   MOV AH,1Ch
  981.   MOV DL,Drive
  982.   INT DOS
  983.   MOV AH,BYTE PTR [DS:BX]
  984.   LES DI,Info
  985.   MOV BYTE PTR ES:[DI],AH      { Info.FATId }
  986.   MOV WORD PTR ES:[DI+1],DX    { Info.Clusters }
  987.   MOV BYTE PTR ES:[DI+3],AL    { Info.SectorsPerCluster }
  988.   MOV WORD PTR ES:[DI+4],CX    { Info.BytesPerSector }
  989.   POP DS
  990. End; { GetDriveAllocInfo }
  991.  
  992. Function GetDPB; assembler;
  993. { GETDPB - DOS disk service function (undocumented)
  994.   Description: Returns a block of information that is useful for applications
  995.                which perform sector-level access of disk drives supported by
  996.                device drivers; fn=32h
  997.   Returns: 0 if successful, negative dosrInvalidDrive error code otherwise
  998.   Remarks: Use 0 for default drive }
  999. Asm
  1000.   MOV DOSResult,dosrOk
  1001.   PUSH DS
  1002.   MOV AH,32h
  1003.   MOV DL,Drive
  1004.   INT DOS
  1005.   MOV WORD PTR [DPB],DS
  1006.   MOV WORD PTR [DPB+2],BX
  1007.   POP DS
  1008.   XOR AH,AH
  1009.   CMP AL,0FFh
  1010.   JNE @@1
  1011.   MOV DOSResult,dosrInvalidDrive
  1012.   PUSH DOSResult
  1013.   PUSH fnGetDPB
  1014.   CALL ErrorHandler
  1015.   MOV AX,DOSResult
  1016.   NEG AX
  1017. @@1:
  1018. End; { GetDPB }
  1019.  
  1020. Function DiskSize; assembler;
  1021. { DISKSIZE - DOS disk service function
  1022.   Description: Retrieves total disk size; fn=36h
  1023.   Returns: Total disk size in bytes if successful, negative dosrInvalidDrive
  1024.            error code otherwise
  1025.   Remarks: Use 0 for default drive }
  1026. Asm
  1027. @@1:
  1028.   MOV AH,36h
  1029.   MOV DL,Drive
  1030.   INT DOS
  1031.   CMP AX,0FFFFh
  1032.   JE  @@2
  1033.   MOV BX,DX
  1034.   IMUL CX
  1035.   IMUL BX
  1036.   JMP @@3
  1037. @@2:
  1038.   MOV DOSResult,dosrInvalidDrive
  1039.   PUSH DOSResult
  1040.   PUSH fnGetDiskSize
  1041.   CALL ErrorHandler
  1042.   CMP AL,frRetry
  1043.   JE  @@1
  1044.   MOV AX,DOSResult
  1045.   NEG AX
  1046.   XOR DX,DX
  1047. @@3:
  1048. End; { DiskSize }
  1049.  
  1050. Function DiskFree; assembler;
  1051. { DISKFREE - DOS disk service function
  1052.   Description: Retrieves amount of free disk space; fn=36h
  1053.   Returns: Amount of free disk space in bytes if successful,
  1054.            negative dosrInvalidDrive error code otherwise
  1055.   Remarks: Use 0 for default drive }
  1056. Asm
  1057. @@1:
  1058.   MOV AH,36h
  1059.   MOV DL,Drive
  1060.   INT DOS
  1061.   CMP AX,0FFFFh
  1062.   JE  @@2
  1063.   IMUL CX
  1064.   IMUL BX
  1065.   JMP @@3
  1066. @@2:
  1067.   MOV DOSResult,dosrInvalidDrive
  1068.   PUSH DOSResult
  1069.   PUSH fnGetDiskFree
  1070.   CALL ErrorHandler
  1071.   CMP AL,frRetry
  1072.   JE  @@1
  1073.   MOV AX,DOSResult
  1074.   NEG AX
  1075.   XOR DX,DX
  1076. @@3:
  1077. End; { DiskFree }
  1078.  
  1079. Function IsFixedDisk; assembler;
  1080. { ISFIXEDDISK - DOS disk service function
  1081.   Description: Ensures whether the specified disk is fixed or removable;
  1082.                fn=4408h
  1083.   Returns: True, if the disk is fixed, False - otherwise
  1084.   Remarks: Use 0 for default (current) drive }
  1085. Asm
  1086.   MOV AX,4408h
  1087.   MOV BL,Drive
  1088.   INT DOS
  1089.   JNC @@1
  1090.   MOV DOSResult,AX { save error code in global variable }
  1091.   PUSH AX     { store error code }
  1092.   PUSH fnIsFixedDisk  { store function code }
  1093.   CALL ErrorHandler
  1094. @@1:
  1095. End; { IsFixedDisk }
  1096.  
  1097. Function IsNetworkDrive; assembler;
  1098. { ISNETWORKDRIVE - DOS disk service function
  1099.   Description: Ensures whether the specified disk drive is a network drive;
  1100.                fn=4409h
  1101.   Returns: True if drive is a network drive, False if it's a local drive
  1102.   Remarks: Use 0 for detecting the default (current) drive }
  1103. Asm
  1104.   MOV AX,4409h
  1105.   MOV BL,Drive
  1106.   INT DOS
  1107.   JNC @@1
  1108.   MOV DOSResult,AX { save error code in global variable }
  1109.   PUSH AX     { store error code }
  1110.   PUSH fnIsNetworkDrive  { store function code }
  1111.   CALL ErrorHandler
  1112. @@1:
  1113. End; { IsNetworkDrive }
  1114.  
  1115. Function GetDriveType(Drive : byte) : byte; assembler;
  1116. { GETDRIVETYPE - Disk service function
  1117.   Description: Detects the type of the specified drive. Uses IsFixedDisk and
  1118.                IsNetworkDrive functions to produce a result value
  1119.   Returns: One of (dt) constants (see const section)
  1120.   Remarks: Use 0 for detecting the default (current) drive }
  1121. Asm
  1122.   PUSH WORD PTR Drive
  1123.   CALL IsNetworkDrive
  1124.   XOR BL,BL
  1125.   CMP DOSResult,dosrOk
  1126.   JNE @@3
  1127.   CMP AL,True
  1128.   JNE @@1
  1129.   MOV BL,dtRemote
  1130.   JMP @@3
  1131. @@1:
  1132.   PUSH WORD PTR Drive
  1133.   CALL IsFixedDisk
  1134.   XOR BL,BL
  1135.   CMP DOSResult,dosrOk
  1136.   JNE @@3
  1137.   CMP AL,True
  1138.   JNE @@2
  1139.   MOV BL,dtFixed
  1140.   JMP @@3
  1141. @@2:
  1142.   MOV BL,dtRemovable
  1143. @@3:
  1144.   MOV AL,BL
  1145. End; { GetDriveType }
  1146.  
  1147. Function CreateDir; assembler;
  1148. { CREATEDIR - DOS directory function
  1149.   Description: Creates a directory; fn=39h
  1150.   Returns: 0 if successful, negative DOS error code otherwise }
  1151. Asm
  1152. @@1:
  1153.   PUSH DS
  1154.   LDS DX,Dir
  1155.   MOV AH,39h
  1156.   INT DOS
  1157.   POP DS
  1158.   JC  @@2
  1159.   XOR AX,AX
  1160.   MOV DOSResult,dosrOk
  1161.   JMP @@3
  1162. @@2:
  1163.   MOV DOSResult,AX { save error code in global variable }
  1164.   PUSH AX     { store error code }
  1165.   PUSH fnCreateDir  { store function code }
  1166.   CALL ErrorHandler
  1167.   CMP AL,frRetry
  1168.   JE  @@1
  1169.   POP AX
  1170.   NEG AX
  1171. @@3:
  1172. End; { CreateDir }
  1173.  
  1174. Function RemoveDir; assembler;
  1175. { REMOVEDIR - DOS directory function
  1176.   Description: Removes (deletes) a directory; fn=3Ah
  1177.   Returns: 0 if successful, negative DOS error code otherwise }
  1178. Asm
  1179. @@1:
  1180.   PUSH DS
  1181.   LDS DX,Dir
  1182.   MOV AH,3Ah
  1183.   INT DOS
  1184.   POP DS
  1185.   JC  @@2
  1186.   XOR AX,AX
  1187.   MOV DOSResult,dosrOk
  1188.   JMP @@3
  1189. @@2:
  1190.   MOV DOSResult,AX { save error code in global variable }
  1191.   PUSH AX     { store error code }
  1192.   PUSH fnRemoveDir  { store function code }
  1193.   CALL ErrorHandler
  1194.   CMP AL,frRetry
  1195.   JE  @@1
  1196.   POP AX
  1197.   NEG AX
  1198. @@3:
  1199. End; { RemoveDir }
  1200.  
  1201. Function GetCurDir; assembler;
  1202. { GETCURDIR - DOS directory function
  1203.   Description: Retrieves current (active) directory name; fn=47h
  1204.   Returns: 0 if successful, negative DOS error code otherwise }
  1205. Asm
  1206. @@1:
  1207.   PUSH DS
  1208.   LDS SI,Dir
  1209.   MOV DL,Drive
  1210.   MOV AH,47h
  1211.   INT DOS
  1212.   POP DS
  1213.   JC  @@2
  1214.   XOR AX,AX
  1215.   MOV DOSResult,dosrOk
  1216.   JMP @@3
  1217. @@2:
  1218.   MOV DOSResult,AX { save error code in global variable }
  1219.   PUSH AX     { store error code }
  1220.   PUSH fnGetCurDir  { store function number }
  1221.   CALL ErrorHandler
  1222.   CMP AL,frRetry
  1223.   JE  @@1
  1224.   POP AX
  1225.   NEG AX
  1226. @@3:
  1227. End; { GetCurDir }
  1228.  
  1229. Function SetCurDir; assembler;
  1230. { SETCURDIR - DOS directory function
  1231.   Description: Sets current (active) directory; fn=3Bh
  1232.   Returns: 0 if successful, negative DOS error code otherwise }
  1233. Asm
  1234. @@1:
  1235.   PUSH DS
  1236.   LDS DX,Dir
  1237.   MOV AH,3Bh
  1238.   INT DOS
  1239.   POP DS
  1240.   JC  @@2
  1241.   XOR AX,AX
  1242.   MOV DOSResult,AX
  1243.   JMP @@3
  1244. @@2:
  1245.   MOV DOSResult,AX { save error code in global variable }
  1246.   PUSH AX     { store error code }
  1247.   PUSH fnSetCurDir  { store function code }
  1248.   CALL ErrorHandler
  1249.   CMP AL,frRetry
  1250.   JE  @@1
  1251.   POP AX
  1252.   NEG AX
  1253. @@3:
  1254. End; { SetCurDir }
  1255.  
  1256. Function DeleteFile; assembler;
  1257. { DELETEFILE - DOS file function
  1258.   Description: Deletes a file; fn=41h
  1259.   Returns: 0 if successful, negative DOS error code otherwise }
  1260. Asm
  1261. @@1:
  1262.   PUSH DS
  1263.   LDS DX,Path
  1264.   MOV AH,41h
  1265.   INT DOS
  1266.   POP DS
  1267.   JC  @@2
  1268.   XOR AX,AX
  1269.   MOV DOSResult,dosrOk
  1270.   JMP @@3
  1271. @@2:
  1272.   MOV DOSResult,AX { save error code in global variable }
  1273.   PUSH AX     { store error code }
  1274.   PUSH fnDeleteFile  { store function code }
  1275.   CALL ErrorHandler
  1276.   CMP AL,frRetry
  1277.   JE  @@1
  1278.   POP AX
  1279.   NEG AX
  1280. @@3:
  1281. End; { DeleteFile }
  1282.  
  1283. Function RenameFile; assembler;
  1284. { RENAMEFILE - DOS file function
  1285.   Description: Renames/moves a file; fn=56h
  1286.   Returns: 0 if successful, negative error code otherwise }
  1287. Asm
  1288. @@1:
  1289.   PUSH DS
  1290.   LDS DX,OldPath
  1291.   LES DI,NewPath
  1292.   MOV AH,56h
  1293.   INT DOS
  1294.   POP DS
  1295.   JC  @@2
  1296.   XOR AX,AX
  1297.   MOV DOSResult,dosrOk
  1298.   JMP @@3
  1299. @@2:
  1300.   MOV DOSResult,AX { save error code in global variable }
  1301.   PUSH AX     { store error code }
  1302.   PUSH fnRenameFile  { store function code }
  1303.   CALL ErrorHandler
  1304.   CMP AL,frRetry
  1305.   JE  @@1
  1306.   POP AX
  1307.   NEG AX
  1308. @@3:
  1309. End; { RenameFile }
  1310.  
  1311. Function ExistsFile; assembler;
  1312. { EXISTSFILE - DOS file function
  1313.   Description: Determines whether the file exists; fn=4Eh
  1314.   Returns: TRUE if the file exists, FALSE - otherwise }
  1315. Asm
  1316.   PUSH DS
  1317.   LDS DX,Path
  1318.   MOV AH,4Eh
  1319.   INT DOS
  1320.   POP DS
  1321.   JNC @@1
  1322.   XOR AL,AL
  1323.   JMP @@2
  1324. @@1:
  1325.   MOV AL,True
  1326. @@2:
  1327. End; { ExistsFile }
  1328.  
  1329. Function GetFileAttr; assembler;
  1330. { GETFILEATTR - DOS file function
  1331.   Description: Gets file attributes; fn=43h,AL=0
  1332.   Returns: File attributes if no error, negative DOS error code otherwise }
  1333. Asm
  1334. @@1:
  1335.   PUSH DS
  1336.   LDS DX,Path
  1337.   MOV AX,4300h
  1338.   INT DOS
  1339.   POP DS
  1340.   JC  @@2
  1341.   MOV AX,CX
  1342.   MOV DOSResult,dosrOk
  1343.   JMP @@3
  1344. @@2:
  1345.   MOV DOSResult,AX { save error code in global variable }
  1346.   PUSH AX     { store error code }
  1347.   PUSH fnGetFileAttr  { store function code }
  1348.   CALL ErrorHandler
  1349.   CMP AL,frRetry
  1350.   JE  @@1
  1351.   POP AX
  1352.   NEG AX
  1353. @@3:
  1354. End; { GetFileAttr }
  1355.  
  1356. Function SetFileAttr; assembler;
  1357. { SETFILEATTR - DOS file function
  1358.   Description: Sets file attributes; fn=43h,AL=1
  1359.   Returns: 0 if no error, negative DOS error code otherwise }
  1360. Asm
  1361. @@1:
  1362.   PUSH DS
  1363.   LDS DX,Path
  1364.   MOV CX,Attr
  1365.   MOV AX,4301h
  1366.   INT DOS
  1367.   POP DS
  1368.   JC  @@2
  1369.   XOR AX,AX
  1370.   MOV DOSResult,dosrOk
  1371.   JMP @@3
  1372. @@2:
  1373.   MOV DOSResult,AX { save error code in global variable }
  1374.   PUSH AX     { store error code }
  1375.   PUSH fnSetFileAttr  { store function code }
  1376.   CALL ErrorHandler
  1377.   CMP AL,frRetry
  1378.   JE  @@1
  1379.   POP AX
  1380.   NEG AX
  1381. @@3:
  1382. End; { GetFileAttr }
  1383.  
  1384. Function FindFirst; assembler;
  1385. { FINDFIRST - DOS file service function
  1386.   Description: Searches the specified (or current) directory for
  1387.                the first entry that matches the specified filename and
  1388.                attributes; fn=4E00h
  1389.   Returns: 0 if successful, negative DOS error code otherwise }
  1390. Asm
  1391. @@1:
  1392.   PUSH DS
  1393.   LDS DX,F
  1394.   MOV AH,1AH
  1395.   INT DOS
  1396.   POP DS
  1397.   LES DI,Path
  1398.   MOV CX,Attr
  1399.   MOV AH,4EH
  1400.   CALL AnsiDosFunc
  1401.   MOV DOSResult,dosrOk
  1402.   JC  @@2
  1403. {$IFDEF Windows}
  1404.   LES DI,F
  1405.   ADD DI,OFFSET TSearchRec.Name
  1406.   PUSH ES
  1407.   PUSH DI
  1408.   PUSH ES
  1409.   PUSH DI
  1410.   CALL OemToAnsi
  1411. {$ENDIF}
  1412.   XOR AX,AX
  1413.   JMP @@3
  1414. @@2:
  1415.   MOV DOSResult,AX { save error code in global variable }
  1416.   PUSH AX     { store error code }
  1417.   PUSH fnFindFirst  { store function code }
  1418.   CALL ErrorHandler
  1419.   CMP AL,frRetry
  1420.   JE  @@1
  1421.   POP AX
  1422. @@3:
  1423.   NEG AX
  1424. End; { FindFirst }
  1425.  
  1426. Function FindNext; assembler;
  1427. { FINDNEXT - DOS file service function
  1428.   Description: Returs the next entry that matches the name and
  1429.                attributes specified in a previous call to FindFirst.
  1430.                The search record must be one passed to FindFirst
  1431.   Returns: 0 if successful, negative DOS error code otherwise }
  1432. Asm
  1433. @@1:
  1434.   PUSH DS
  1435.   LDS DX,F
  1436.   MOV AH,1AH
  1437.   INT DOS
  1438.   POP DS
  1439.   MOV AH,4FH
  1440.   MOV DOSResult,dosrOk
  1441.   INT DOS
  1442.   JC  @@2
  1443. {$IFDEF Windows}
  1444.   LES DI,F
  1445.   ADD DI,OFFSET TSearchRec.Name
  1446.   PUSH ES
  1447.   PUSH DI
  1448.   PUSH ES
  1449.   PUSH DI
  1450.   CALL OemToAnsi
  1451. {$ENDIF}
  1452.   XOR AX,AX
  1453.   JMP @@3
  1454. @@2:
  1455.   MOV DOSResult,AX { save error code in global variable }
  1456.   PUSH AX     { store error code }
  1457.   PUSH fnFindNext  { store function code }
  1458.   CALL ErrorHandler
  1459.   CMP AL,frRetry
  1460.   JE  @@1
  1461.   POP AX
  1462. @@3:
  1463.   NEG AX
  1464. End; { FindNext }
  1465.  
  1466. Procedure UnpackTime; assembler;
  1467. { UNPACKTIME - Service function
  1468.   Description: Converts a 4-byte packed date/time returned by
  1469.                FindFirst, FindNext or GetFTime into a TDateTime record }
  1470. Asm
  1471.   LES DI,T
  1472.   CLD
  1473.   MOV AX,WORD PTR [P+2]
  1474.   MOV CL,9
  1475.   SHR AX,CL
  1476.   ADD AX,1980
  1477.   STOSW
  1478.   MOV AX,WORD PTR [P+2]
  1479.   MOV CL,5
  1480.   SHR AX,CL
  1481.   AND AX,15
  1482.   STOSW
  1483.   MOV AX,WORD PTR [P+2]
  1484.   AND AX,31
  1485.   STOSW
  1486.   MOV AX,P.Word[0]
  1487.   MOV CL,11
  1488.   SHR AX,CL
  1489.   STOSW
  1490.   MOV AX,WORD PTR [P+2]
  1491.   MOV CL,5
  1492.   SHR AX,CL
  1493.   AND AX,63
  1494.   STOSW
  1495.   MOV AX,WORD PTR [P]
  1496.   AND AX,31
  1497.   SHL AX,1
  1498.   STOSW
  1499. End; { UnpackTime }
  1500.  
  1501. Function PackTime; assembler;
  1502. { PACKTIME - Service function
  1503.   Decription: Converts a TDateTime record into a 4-byte packed
  1504.               date/time used by SetFTime
  1505.   Returns: 4-byte long integer corresponding to packed date/time }
  1506. Asm
  1507.   PUSH DS
  1508.   LDS SI,T
  1509.   CLD
  1510.   LODSW
  1511.   SUB AX,1980
  1512.   MOV CL,9
  1513.   SHL AX,CL
  1514.   XCHG AX,DX
  1515.   LODSW
  1516.   MOV CL,5
  1517.   SHL AX,CL
  1518.   ADD DX,AX
  1519.   LODSW
  1520.   ADD DX,AX
  1521.   LODSW
  1522.   MOV CL,11
  1523.   SHL AX,CL
  1524.   XCHG AX,BX
  1525.   LODSW
  1526.   MOV CL,5
  1527.   SHL AX,CL
  1528.   ADD BX,AX
  1529.   LODSW
  1530.   SHR AX,1
  1531.   ADD AX,BX
  1532.   POP DS
  1533. End; { PackTime }
  1534.  
  1535. Function h_CreateFile; assembler;
  1536. { H_CREATEFILE - DOS Handle file function
  1537.   Description: Creates a file; fn=3Ch
  1538.   Returns: File handle if successful, 0 if unsuccessful }
  1539. Asm
  1540. @@1:
  1541.   PUSH DS
  1542.   LDS DX,Path
  1543.   MOV CX,0
  1544.   MOV AH,5Bh
  1545.   INT DOS
  1546.   POP DS
  1547.   JC  @@2
  1548.   MOV DOSResult,dosrOk
  1549.   JMP @@3
  1550. @@2:
  1551.   MOV DOSResult,AX { save error code in global variable }
  1552.   PUSH AX     { store error code }
  1553.   PUSH fnCreateFile  { store function code }
  1554.   CALL ErrorHandler
  1555.   CMP AL,frRetry
  1556.   JE  @@1
  1557.   XOR AX,AX
  1558. @@3:
  1559. End; { h_CreateFile }
  1560.  
  1561. Function h_CreateTempFile; assembler;
  1562. { H_CREATETEMPFILE - DOS Handle file function
  1563.   Description: Creates a temporary file; fn=5Ah
  1564.   Returns: File handle if successful, 0 if unsuccessful }
  1565. Asm
  1566. @@1:
  1567.   PUSH DS
  1568.   LDS DX,Path
  1569.   MOV CX,0 { file attribute here, 0 used for normal }
  1570.   MOV AH,5Ah
  1571.   INT DOS
  1572.   POP DS
  1573.   JC  @@2
  1574.   MOV DOSResult,dosrOk
  1575.   JMP @@3
  1576. @@2:
  1577.   MOV DOSResult,AX { save error code in global variable }
  1578.   PUSH AX     { store error code }
  1579.   PUSH fnCreateTempFile  { store function code }
  1580.   CALL ErrorHandler
  1581.   CMP AL,frRetry
  1582.   JE  @@1
  1583.   XOR AX,AX
  1584. @@3:
  1585. End; { h_CreateTempFile }
  1586.  
  1587. Function h_OpenFile; assembler;
  1588. { H_OPENFILE - DOS Handle file function
  1589.   Description: Opens a file for input, output or input/output; fn=3Dh
  1590.   Returns: File handle if successful, 0 if unsuccessful }
  1591. Asm
  1592. @@1:
  1593.   PUSH DS
  1594.   LDS DX,Path
  1595.   MOV AH,3Dh
  1596.   MOV AL,Mode
  1597.   INT DOS
  1598.   POP DS
  1599.   JC  @@2
  1600.   MOV DOSResult,dosrOk
  1601.   JMP @@3
  1602. @@2:
  1603.   MOV DOSResult,AX { save error code in global variable }
  1604.   PUSH AX     { store error code }
  1605.   PUSH fnOpenFile  { store function code }
  1606.   CALL ErrorHandler
  1607.   CMP AL,frRetry
  1608.   JE  @@1
  1609.   XOR AX,AX
  1610. @@3:
  1611. End; { h_OpenFile }
  1612.  
  1613. Function h_Read; assembler;
  1614. { H_READ - DOS Handle file function
  1615.   Description: Reads a memory block from file; fn=3Fh
  1616.   Returns: Actual number of bytes read }
  1617. Asm
  1618. @@1:
  1619.   PUSH DS
  1620.   LDS DX,Buffer
  1621.   MOV CX,Count
  1622.   MOV BX,Handle
  1623.   MOV AH,3Fh
  1624.   INT DOS
  1625.   POP DS
  1626.   MOV DOSResult,dosrOk
  1627.   JNC @@2
  1628.   MOV DOSResult,AX { save error code in global variable }
  1629.   PUSH AX     { store error code }
  1630.   PUSH fnRead  { store function code }
  1631.   CALL ErrorHandler
  1632.   CMP AL,frRetry
  1633.   JE  @@1
  1634. @@2:
  1635. End; { h_Read }
  1636.  
  1637. Function h_Write; assembler;
  1638. { H_WRITE - DOS Handle file function
  1639.   Description: Writes a memory block to file; fn=40h
  1640.   Returns: Actual number of bytes written }
  1641. Asm
  1642. @@1:
  1643.   PUSH DS
  1644.   LDS DX,Buffer
  1645.   MOV CX,Count
  1646.   MOV BX,Handle
  1647.   MOV AH,40h
  1648.   INT DOS
  1649.   POP DS
  1650.   MOV DOSResult,dosrOk
  1651.   JNC @@2
  1652.   MOV DOSResult,AX { save error code in global variable }
  1653.   PUSH AX     { store error code }
  1654.   PUSH fnWrite  { store function code }
  1655.   CALL ErrorHandler
  1656.   CMP AL,frRetry
  1657.   JE  @@1
  1658. @@2:
  1659. End; { h_Write }
  1660.  
  1661. Function h_Seek; assembler;
  1662. { H_SEEK - DOS Handle file function
  1663.   Description: Seeks to a specified file position; fn=42h
  1664.                Start is one of the (sk) constants and points to a relative
  1665.                seek offset position
  1666.   Returns: Current file position if successful, 0 - otherwise }
  1667. Asm
  1668. @@1:
  1669.   MOV CX,WORD PTR [SeekPos+2]
  1670.   MOV DX,WORD PTR [SeekPos]
  1671.   MOV BX,Handle
  1672.   MOV AL,Start
  1673.   MOV AH,42h
  1674.   MOV DOSResult,dosrOk
  1675.   INT DOS
  1676.   JNC @@2
  1677.   MOV DOSResult,AX { save error code in global variable }
  1678.   PUSH AX     { store error code }
  1679.   PUSH fnSeek  { store function number }
  1680.   CALL ErrorHandler
  1681.   CMP AL,frRetry
  1682.   JE  @@1
  1683. @@2:
  1684. End; { h_Seek }
  1685.  
  1686. Function h_FilePos;
  1687. { H_GETPOS - DOS Handle file function
  1688.   Description: Calls h_Seek to determine file active position
  1689.   Returns: Current file (seek) position number in long integer }
  1690. Begin
  1691.   h_FilePos := h_Seek(Handle, 0, skPos)
  1692. End; { h_FilePos }
  1693.  
  1694. Function h_FileSize;
  1695. { H_FILESIZE - DOS Handle file function
  1696.   Description: Determines file size
  1697.   Returns: File size in bytes }
  1698. var SavePos, Size : longint;
  1699. Begin
  1700.   SavePos := h_FilePos(Handle);
  1701.   h_FileSize := h_Seek(Handle, 0, skEnd);
  1702.   h_Seek(Handle, SavePos, skStart)
  1703. End; { h_FileSize }
  1704.  
  1705. Function h_Eof; assembler;
  1706. { H_EOF - DOS Handle file function
  1707.   Description: Checks if the current file position is equal to file size
  1708.                and then returns True
  1709.   Returns: True if end of file detected, False - otherwise }
  1710. var Size : longint;
  1711. Asm
  1712.   PUSH Handle
  1713.   CALL h_FileSize               { Get file size in AX:DX }
  1714.   MOV WORD PTR [Size],AX        { Store high word }
  1715.   MOV WORD PTR [Size+2],DX      { Store low word }
  1716.   PUSH Handle
  1717.   CALL h_FilePos                 { Get current file position }
  1718.   XOR CL,CL
  1719.   CMP AX,WORD PTR [Size]
  1720.   JNE @@1
  1721.   CMP DX,WORD PTR [Size+2]
  1722.   JNE @@1
  1723.   MOV CL,True
  1724. @@1:
  1725.   MOV AL,CL
  1726. End; { h_GetPos }
  1727.  
  1728. Function h_GetFTime; assembler;
  1729. { H_GETFTIME - DOS Handle file function
  1730.   Description: Returns file update date and time values; fn=5700h
  1731.   Returns: Date and time values in long integer
  1732.            or negative DOS error code if an error occured }
  1733. Asm
  1734. @@1:
  1735.   MOV BX,Handle
  1736.   MOV AX,5700h { read date and time }
  1737.   MOV DOSResult,dosrOk
  1738.   INT DOS
  1739.   JNC @@2
  1740.   MOV DOSResult,AX { save error code in global variable }
  1741.   PUSH AX     { store error code }
  1742.   PUSH fnGetFDateTime  { store function number }
  1743.   CALL ErrorHandler
  1744.   CMP AL,frRetry
  1745.   JE  @@1
  1746.   POP AX
  1747.   NEG AX
  1748. @@2:
  1749. End; { h_GetFTime }
  1750.  
  1751. Function h_SetFTime; assembler;
  1752. { H_SETFTIME - DOS Handle file function
  1753.   Description: Sets file date and time; fn=5701h
  1754.   Returns: New date and time values in long integer
  1755.            or negative DOS error code if an error occured }
  1756. Asm
  1757. @@1:
  1758.   MOV CX,WORD PTR [DateTime]
  1759.   MOV DX,WORD PTR [DateTime+2]
  1760.   MOV BX,Handle
  1761.   MOV AX,5701h { read date and time }
  1762.   MOV DOSResult,dosrOk
  1763.   INT DOS
  1764.   JNC @@2
  1765.   MOV DOSResult,AX { save error code in global variable }
  1766.   PUSH AX     { store error code }
  1767.   PUSH fnSetFDateTime  { store function number }
  1768.   CALL ErrorHandler
  1769.   CMP AL,frRetry
  1770.   JE  @@1
  1771.   POP AX
  1772.   NEG AX
  1773. @@2:
  1774. End; { h_SetFTime }
  1775.  
  1776. Function h_CloseFile; assembler;
  1777. { H_CLOSEFILE - DOS Handle file function
  1778.   Description: Closes open file; fn=3Eh
  1779.   Returns: 0 if successful, negative DOS error code otherwise }
  1780. Asm
  1781. @@1:
  1782.   MOV BX,Handle
  1783.   MOV AH,3Eh
  1784.   INT DOS
  1785.   JC  @@2
  1786.   XOR AX,AX
  1787.   MOV DOSResult,dosrOk
  1788.   JMP @@3
  1789. @@2:
  1790.   MOV DOSResult,AX { save error code in global variable }
  1791.   PUSH AX     { store error code }
  1792.   PUSH fnCloseFile  { store function number }
  1793.   CALL ErrorHandler
  1794.   CMP AL,frRetry
  1795.   JE  @@1
  1796.   POP AX
  1797.   NEG AX
  1798. @@3:
  1799. End; { h_CloseFile }
  1800.  
  1801. Function MemAlloc; assembler;
  1802. Asm
  1803. @@1:
  1804.   MOV DOSResult,dosrOk
  1805.   MOV AX,WORD PTR [Size]
  1806.   MOV DX,WORD PTR [Size+2]
  1807.   MOV CX,16
  1808.   DIV CX
  1809.   INC AX
  1810.   MOV BX,AX
  1811.   MOV AH,48h
  1812.   INT DOS
  1813.   JNC @@2
  1814.   MOV DOSResult,AX { save error code in global variable }
  1815.   PUSH AX     { store error code }
  1816.   PUSH fnMemAlloc  { store function number }
  1817.   CALL ErrorHandler
  1818.   CMP AL,frRetry
  1819.   JE  @@1
  1820.   XOR AX,AX
  1821. @@2:
  1822.   MOV DX,AX
  1823.   XOR AX,AX
  1824. End; { MemAlloc }
  1825.  
  1826. Function MemFree; assembler;
  1827. Asm
  1828.   MOV DOSResult,dosrOk
  1829.   MOV ES,WORD PTR [P+2]
  1830.   MOV AH,49h
  1831.   INT DOS
  1832.   JNC @@1
  1833.   MOV DOSResult,AX
  1834.   PUSH AX
  1835.   PUSH fnMemFree
  1836.   CALL ErrorHandler
  1837. @@1:
  1838.   MOV AX,DOSResult
  1839.   NEG AX
  1840. End; { MemFree }
  1841.  
  1842. Function FileSearch; assembler;
  1843. { FileSearch searches for the file given by Name in the list of }
  1844. { directories given by List. The directory paths in List must   }
  1845. { be separated by semicolons. The search always starts with the }
  1846. { current directory of the current drive. If the file is found, }
  1847. { FileSearch stores a concatenation of the directory path and   }
  1848. { the file name in Dest. Otherwise FileSearch stores an empty   }
  1849. { string in Dest. The maximum length of the result is defined   }
  1850. { by the fsPathName constant. The returned value is Dest.       }
  1851. Asm
  1852.   PUSH DS
  1853.   CLD
  1854.   LDS SI,List
  1855.   LES DI,Dest
  1856.   MOV CX,fsPathName
  1857. @@1:
  1858.   PUSH DS
  1859.   PUSH SI
  1860.   JCXZ @@3
  1861.   LDS SI,Name
  1862. @@2:
  1863.   LODSB
  1864.   OR  AL,AL
  1865.   JE  @@3
  1866.   STOSB
  1867.   LOOP @@2
  1868. @@3:
  1869.   XOR AL,AL
  1870.   STOSB
  1871.   LES DI,Dest
  1872.   MOV AX,4300H
  1873.   CALL AnsiDosFunc
  1874.   POP SI
  1875.   POP DS
  1876.   JC  @@4
  1877.   TEST CX,18H
  1878.   JE  @@9
  1879. @@4:
  1880.   LES DI,Dest
  1881.   MOV CX,fsPathName
  1882.   XOR AH,AH
  1883.   LODSB
  1884.   OR  AL,AL
  1885.   JE  @@8
  1886. @@5:
  1887.   CMP AL,';'
  1888.   JE  @@7
  1889.   JCXZ @@6
  1890.   MOV AH,AL
  1891.   STOSB
  1892.   DEC CX
  1893. @@6:
  1894.   LODSB
  1895.   OR  AL,AL
  1896.   JNE @@5
  1897.   DEC SI
  1898. @@7:
  1899.   JCXZ @@1
  1900.   CMP AH,':'
  1901.   JE  @@1
  1902.   MOV AL,'\'
  1903.   CMP AL,AH
  1904.   JE  @@1
  1905.   STOSB
  1906.   DEC CX
  1907.   JMP @@1
  1908. @@8:
  1909.   STOSB
  1910. @@9:
  1911.   MOV AX,WORD PTR [Dest]
  1912.   MOV DX,WORD PTR [Dest+2]
  1913.   POP DS
  1914. End; { FileSearch }
  1915.  
  1916. Function FileExpand; assembler;
  1917. { FileExpand fully expands the file name in Name, and stores    }
  1918. { the result in Dest. The maximum length of the result is       }
  1919. { defined by the fsPathName constant. The result is an all }
  1920. { upper case string consisting of a drive letter, a colon, a }
  1921. { root relative directory path, and a file name. Embedded '.' }
  1922. { and '..' directory references are removed, and all name and }
  1923. { extension components are truncated to 8 and 3 characters. The }
  1924. { returned value is Dest.                }
  1925.  
  1926. Asm
  1927.   PUSH DS
  1928.   CLD
  1929.   LDS SI,Name
  1930.   LEA DI,TempStr
  1931.   PUSH SS
  1932.   POP ES
  1933.   LODSW
  1934.   OR  AL,AL
  1935.   JE  @@1
  1936.   CMP AH,':'
  1937.   JNE @@1
  1938.   CMP AL,'a'
  1939.   JB  @@2
  1940.   CMP AL,'z'
  1941.   JA  @@2
  1942.   SUB AL,20H
  1943.   JMP @@2
  1944. @@1:
  1945.   DEC SI
  1946.   DEC SI
  1947.   MOV AH,19H
  1948.   INT DOS
  1949.   ADD AL,'A'
  1950.   MOV AH,':'
  1951. @@2:
  1952.   STOSW
  1953.   CMP [SI].Byte,'\'
  1954.   JE  @@3
  1955.   SUB AL,'A'-1
  1956.   MOV DL,AL
  1957.   MOV AL,'\'
  1958.   STOSB
  1959.   PUSH DS
  1960.   PUSH SI
  1961.   MOV AH,47H
  1962.   MOV SI,DI
  1963.   PUSH ES
  1964.   POP DS
  1965.   INT DOS
  1966.   POP SI
  1967.   POP DS
  1968.   JC  @@3
  1969.   XOR AL,AL
  1970.   CMP AL,ES:[DI]
  1971.   JE  @@3
  1972. {$IFDEF Windows}
  1973.   PUSH ES
  1974.   PUSH ES
  1975.   PUSH DI
  1976.   PUSH ES
  1977.   PUSH DI
  1978.   CALL OemToAnsi
  1979.   POP ES
  1980. {$ENDIF}
  1981.   MOV CX,0FFFFH
  1982.   XOR AL,AL
  1983.   CLD
  1984.   REPNE SCASB
  1985.   DEC DI
  1986.   MOV AL,'\'
  1987.   STOSB
  1988. @@3:
  1989.   MOV CX,8
  1990. @@4:
  1991.   LODSB
  1992.   OR  AL,AL
  1993.   JE  @@7
  1994.   CMP AL,'\'
  1995.   JE  @@7
  1996.   CMP AL,'.'
  1997.   JE  @@6
  1998.   JCXZ @@4
  1999.   DEC CX
  2000. {$IFNDEF Windows}
  2001.   CMP AL,'a'
  2002.   JB  @@5
  2003.   CMP AL,'z'
  2004.   JA  @@5
  2005.   SUB AL,20H
  2006. {$ENDIF}
  2007. @@5:
  2008.   STOSB
  2009.   JMP @@4
  2010. @@6:
  2011.   MOV CL,3
  2012.   JMP @@5
  2013. @@7:
  2014.   CMP ES:[DI-2].Word,'.\'
  2015.   JNE @@8
  2016.   DEC DI
  2017.   DEC DI
  2018.   JMP @@10
  2019. @@8:
  2020.   CMP ES:[DI-2].Word,'..'
  2021.   JNE @@10
  2022.   CMP ES:[DI-3].Byte,'\'
  2023.   JNE @@10
  2024.   SUB DI,3
  2025.   CMP ES:[DI-1].Byte,':'
  2026.   JE  @@10
  2027. @@9:
  2028.   DEC DI
  2029.   CMP ES:[DI].Byte,'\'
  2030.   JNE @@9
  2031. @@10:
  2032.   MOV CL,8
  2033.   OR  AL,AL
  2034.   JNE @@5
  2035.   CMP ES:[DI-1].Byte,':'
  2036.   JNE @@11
  2037.   MOV AL,'\'
  2038.   STOSB
  2039. @@11:
  2040.   LEA SI,TempStr
  2041.   PUSH SS
  2042.   POP DS
  2043.   MOV CX,DI
  2044.   SUB CX,SI
  2045.   CMP CX,79
  2046.   JBE @@12
  2047.   MOV CX,79
  2048. @@12:
  2049.   LES DI,Dest
  2050.   PUSH ES
  2051.   PUSH DI
  2052. {$IFDEF Windows}
  2053.   PUSH ES
  2054.   PUSH DI
  2055. {$ENDIF}
  2056.   REP MOVSB
  2057.   XOR AL,AL
  2058.   STOSB
  2059. {$IFDEF Windows}
  2060.   CALL AnsiUpper
  2061. {$ENDIF}
  2062.   POP AX
  2063.   POP DX
  2064.   POP DS
  2065. End; { FileExpand }
  2066.  
  2067. {$W+}
  2068. Function FileSplit;
  2069. { FileSplit splits the file name specified by Path into its     }
  2070. { three components. Dir is set to the drive and directory path  }
  2071. { with any leading and trailing backslashes, Name is set to the }
  2072. { file name, and Ext is set to the extension with a preceding   }
  2073. { period. If a component string parameter is NIL, the           }
  2074. { corresponding part of the path is not stored. If the path     }
  2075. { does not contain a given component, the returned component    }
  2076. { string is empty. The maximum lengths of the strings returned  }
  2077. { in Dir, Name, and Ext are defined by the fsDirectory,         }
  2078. { fsFileName, and fsExtension constants. The returned value is  }
  2079. { a combination of the fcDirectory, fcFileName, and fcExtension }
  2080. { bit masks, indicating which components were present in the    }
  2081. { path. If the name or extension contains any wildcard          }
  2082. { characters (* or ?), the fcWildcards flag is set in the       }
  2083. { returned value.                                               }
  2084. var
  2085.   DirLen, NameLen, Flags : word;
  2086.   NamePtr, ExtPtr : PChar;
  2087. begin
  2088.   NamePtr := StrRScan(Path, '\');
  2089.   if NamePtr = nil then NamePtr := StrRScan(Path, ':');
  2090.   if NamePtr = nil then NamePtr := Path else Inc(NamePtr);
  2091.   ExtPtr := StrScan(NamePtr, '.');
  2092.   if ExtPtr = nil then ExtPtr := StrEnd(NamePtr);
  2093.   DirLen := NamePtr - Path;
  2094.   if DirLen > fsDirectory then DirLen := fsDirectory;
  2095.   NameLen := ExtPtr - NamePtr;
  2096.   if NameLen > fsFilename then NameLen := fsFilename;
  2097.   Flags := 0;
  2098.   if (StrScan(NamePtr, '?') <> nil) or (StrScan(NamePtr, '*') <> nil) then
  2099.     Flags := fcWildcards;
  2100.   if DirLen <> 0 then Flags := Flags or fcDirectory;
  2101.   if NameLen <> 0 then Flags := Flags or fcFilename;
  2102.   if ExtPtr[0] <> #0 then Flags := Flags or fcExtension;
  2103.   if Dir <> nil then StrLCopy(Dir, Path, DirLen);
  2104.   if Name <> nil then StrLCopy(Name, NamePtr, NameLen);
  2105.   if Ext <> nil then StrLCopy(Ext, ExtPtr, fsExtension);
  2106.   FileSplit := Flags;
  2107. End; { FileSplit }
  2108. {$W-}
  2109.  
  2110. Function StdErrorProc(ErrCode : integer; FuncCode : word) : byte; far;
  2111. assembler;
  2112. { Default error handler procedure called from EnhDOS functions }
  2113. Asm
  2114.   MOV AL,frOk   { Return zero }
  2115. End; { StdErrorProc }
  2116.  
  2117.  
  2118. const WrongDOSVersion : PChar = 'DOS 3.1 or greater required.'#13#10'$';
  2119.  
  2120. Begin
  2121.   asm
  2122.     MOV AH,30h { Get DOS version }
  2123.     INT DOS
  2124.     CMP AL,3
  2125.     JGE @@continue { if greater than or equal to 3 then continue else exit }
  2126.     PUSH DS
  2127.     LDS DX,WrongDOSVersion
  2128.     MOV AH,09h
  2129.     INT DOS
  2130.     MOV AH,4Ch
  2131.     INT DOS
  2132.   @@continue:
  2133.     LES DI,Copyright
  2134.   end;
  2135.   DOSResult := dosrOk;
  2136.   SetErrorHandler(StdErrorProc)
  2137. End. { EnhDOS+ }
  2138.  
  2139.